function GoogleMaps(){
    var obj = new Object();
    
    obj.map = null;
    obj.geocoder = null;
    obj.line = null;
    obj.distance_default = 0;
    obj.center_lat = 0;
    obj.center_lng = 0;
    obj.center_point = null;
    obj.arrPoints = [];
    obj.arrAddress = new Object();
            
    obj.icon = new GIcon(); 
    obj.icon.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
    obj.icon.iconSize = new GSize(12, 20);
    obj.icon.shadowSize = new GSize(22, 20);
    obj.icon.iconAnchor = new GPoint(6, 20);
    obj.icon.infoWindowAnchor = new GPoint(5, 1);
        
    obj.init = function(address, radius) {
        if (GBrowserIsCompatible()) {
            obj.map = new GMap2(document.getElementById("map"));
            obj.map.addControl(new GLargeMapControl()); 
            obj.map.addControl(new GMapTypeControl()); 
            obj.map.setCenter(new GLatLng(37.4419, -122.1419), 12);
            obj.map.enableScrollWheelZoom();
            
            obj.geocoder = new GClientGeocoder();
            
            obj.drawCenter(address, radius);
            obj.drawAddress();
         }       
    }
    
    obj.drawCenter = function(address, radius) {
        if (address == '') {
            return;
        }
        
        radius = parseFloat(radius);
        radius = (radius > 0) ? radius : 1;
        
        if (obj.geocoder) {
            obj.geocoder.getLatLng(
                address,
                function(point) {
                    if (!point) {
                        alert("We're sorry but '" + address + "' cannot be found on Google Maps. Please try again.");
                    } else {
                        obj.center_point = point;
                        obj.map.panTo(point);
                        obj.drawCircle(point, radius); 
                    }
                });
        }
    }
        
    obj.drawCircle = function(point, radius) {
        poly = [];
        
        var lat = point.lat();
        obj.center_lat = lat;
        
        var lng = point.lng();
        obj.center_lng = lng;
        
        var d2r = Math.PI/180; // degrees to radians
        var r2d = 180/Math.PI; // radians to degrees
        var Clat = (radius/3963) * r2d; //  using 3963 as earth's radius
        var Clng = Clat/Math.cos(lat*d2r);
        
        //Add each point in the circle
        for (var i = 0 ; i < 360 ; i++) {
            var theta = Math.PI * (i / 180);
            Cx = lng + (Clng * Math.cos(theta));
            Cy = lat + (Clat * Math.sin(theta));
            poly.push(new GLatLng(Cy,Cx));
        }
                
        //Remove the old line if it exists
        if(obj.line){
            obj.map.removeOverlay(obj.line);
        }
        
        //Add the first point to complete the circle
        poly.push(poly[0]);
        
        //Calc distance default
        if (poly[0]) {
            obj.distance_default = obj.getDistance(lat, lng, poly[0].lat(), poly[0].lng());
        }

        //Create a line with teh points from poly, red, 1 pixels wide, 80% opaque
        obj.line = new GPolyline(poly,'#FF0000', 1, 0.8) ;
        
        obj.map.addOverlay(obj.line);
                
        obj.map.setCenter(point, obj.map.getBoundsZoomLevel( obj.getMBR( poly ))) ;
    }
    
    
        
    obj.getMBR = function(points) {
        var minx = 0;
        var miny = 0;
        var maxx = 0;
        var maxy = 0;
 
        if ( points.length < 4 ) {
            return ( GLatLngBounds(new GLatlng(minx,miny), new GLatlng(maxx,maxy)) ) ;
        }
 
        minx = points[0].lat() ;
        miny = points[0].lng() ;
        maxx = points[0].lat() ;
        maxy = points[0].lng() ;
 
        for(var i = 1; i < points.length ; i++ ) {
            if ( points[i].lat() > maxx ) {
                maxx = points[i].lat() ;
            }
            
            if ( points[i].lat() < minx ) {
                minx = points[i].lat() ;
            }
            
            if ( points[i].lng() > maxy ) {
                maxy = points[i].lng() ;
            }
            
            if ( points[i].lng() < miny ) {
                miny = points[i].lng() ;
            }
        }
        
        return ( new GLatLngBounds(new GLatLng(maxx,miny), new GLatLng(minx,maxy)) ) ;
    }
    
    obj.getDistance = function(lat1,lon1,lat2,lon2) {
        var R = 6371; // km (change this constant to get miles)
        var dLat = (lat2-lat1) * Math.PI / 180;
        var dLon = (lon2-lon1) * Math.PI / 180; 
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) * 
                Math.sin(dLon/2) * Math.sin(dLon/2); 
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
        var d = R * c;
                
        return d;
    }
            
    obj.drawPoint = function(x, y){
        var distance = obj.getDistance(obj.center_lat, obj.center_lng, x, y);
        if (obj.distance_default >= distance) {
            obj.icon.image = 'http://labs.google.com/ridefinder/images/mm_20_blue.png';
        } else {
            obj.icon.image = 'http://labs.google.com/ridefinder/images/mm_20_red.png';
        }
        
        var point = new GLatLng(x, y);
        var marker = new GMarker(point, obj.icon);
        obj.arrPoints.push(marker);
        obj.map.addOverlay(marker);
    }
    
    obj.clearPoint = function() {
        for(var i=0;i<obj.arrPoints.length;i++) {
            obj.map.removeOverlay(obj.arrPoints[i]);
        }
    }
    
    obj.radiusChanged = function(radius) {
        var point = obj.center_point;
        
        obj.drawCircle(point, radius);
        obj.drawAddress();
    }
    
    obj.drawAddress = function() {
        if (!obj.arrAddress) {
            return;
        }
        var arrAddress = obj.arrAddress;
        for (var i in obj.arrAddress) {
            var address = obj.arrAddress[i].address;
            
            if (obj.geocoder) {
                obj.geocoder.getLatLng(
                    address,
                    function(point) {
                        if (point) {
                            var x = point.lat();
                            var y = point.lng();
                            obj.drawPoint(x, y); 
                        }
                    });
            }
        }
    }
        
    return obj;
}

var _GoogleMaps_ = new GoogleMaps();

function CreateNewAddress(address) {
    var obj = new Object();
    
    obj.address = address;
    
    return obj;
}